#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
autor : Filipe Vieira
objectivos :
Gerador de numeros pseudo aleatórios
'''
import random
import time
import sys


def conv(T):    
    ''' 
    Função que verifica se a matriz T (aleatória) converge numa matriz ordenada
    Consiste na analise de sequencias de numeros na matriz T.
    O teste de convergencia é positivo quando na matriz existem
    quatro posições seguidas com o mesmo valor. O facto de serem testadas quatro
    posições tem a haver com o calculo de z1..z4 e a possibilidade de destes resultarem
    em situações de excepção, como por exemplo:
     z1=9 z2=9 z3=9 z4=9  T[0]=9  T[999]=9  N=39321
  
    Entradas: matriz T de 1000 posições
    Saidas: inteiro (0-sem convergencia 1-convergente)
    '''
    flag = 0
    i = 0
    while ((i < 997) & (flag == 0)):
        if ((T[i] == T[i+1])&(T[i+1] == T[i+2])&(T[i+2] == T[i+3])):
            flag = 1
            pass
        i += 1
        pass
    return flag

def preencher_tabela(T):
    ''' 
    Função que efectua o preenchimento de uma matriz
    com valores aleatórios de 0 a 9. Esta função implementa
    validação para que #{0} = #{1} = ... = #{9}.
 
    Entrada: array de 1000 posições
    Saida: contagem por numero de 0 a 9
    '''
    tab_contagem = [0 for x in range(0,10)]
    i = 0
    while i < 1000:
        x = random.randint(0,9)  
        if tab_contagem[x] < 100:
            tab_contagem[x] += 1
            T[i] = x
            i += 1
        pass
    return tab_contagem    

def rand2(T, totnums):
    """ 
        Função que implemeta o algoritmo de geração de numeros pseudo-aletatórios
        apresentado no enunciado do trabalho proposto.
    
        Entrada: nenhuma
        Saida: T (array de numeros)
    """
    p = random.randint(0,999) 
    for i in range(0,totnums):

        while (conv(T) == 1):
            preencher_tabela(T)
            pass

        if p>=1000:
            p = 0;
            pass
        l = p
        T[l], T[0] = T[0], T[l]
        z1 = T[0]

        if (p<999):
            l = p + 1
        else:
            l = 0
        T[l], T[0] = T[0], T[l]
        z2 = T[0]

        if (p<998):
            l = p + 2
        else:
            l = 0
        T[l], T[0] = T[0], T[l]
        z3 = T[0]

        if (p<997):
            l = p + 3
        else:
            l = 0
        T[l], T[0] = T[0], T[l]
        z4 = T[0]

        N = z1 << 12 | z2 << 8 | z3 << 4 | z4
        p = z1 * 100 + z2 * 10 + z3 * 1 +1
        print N
        pass
    return


'''
    Tabela de numeros aleatórios de 0 a 9
    1000 posições
    Utilizada para calculo de z1..z4 e N
'''
T = [0 for x in range(0,1000)]

if (len(sys.argv) > 1):
    totnums = sys.argv[1]
else:
    totnums = 10000
    pass
print totnums

random.seed

t1 = time.clock()
contagem = preencher_tabela(T)      
t2 = time.clock()
rand2(T, totnums)
t3 = time.clock()
print "tempo preenchimento de T:{0}".format(t2-t1)
print "tempo algoritmo:{0}".format(t3-t2)

##print len(T)
##print T
##contagem(T)
